package com.github.tommas.admintpl.controller;

import com.auth0.jwt.algorithms.Algorithm;
import com.github.tommas.admintpl.bean.model.User;
import com.github.tommas.admintpl.bean.vo.AccountInfo;
import com.github.tommas.admintpl.common.CommonResult;
import com.github.tommas.admintpl.config.SecurityConfiguration;
import com.github.tommas.admintpl.security.AccountRealm;
import com.github.tommas.admintpl.security.LoginAuthenticationFilter;
import com.github.tommas.admintpl.security.exception.AccountNotFoundException;
import com.github.tommas.admintpl.service.AccountService;
import com.github.tommas.admintpl.service.UserService;
import com.github.tommas.admintpl.util.JWTUtils;
import lombok.Data;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
public class LoginController {
    @Autowired
    AccountService accountService;

    @Autowired
    UserService userService;

    @Autowired
    Algorithm algorithm;

    @Data
    public static class LoginResult {
        private String token;
        private AccountInfo accountInfo;
    }

    @PostMapping(value = SecurityConfiguration.LOGIN_URL)
    public CommonResult<LoginResult> login(HttpServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            Class exception = (Class) request.getAttribute(LoginAuthenticationFilter.AUTHENTICATION_EXCEPTION_CLASS_ATTR);
            if (exception == null) {
                return CommonResult.failed();
            }

            String message = "Unknown login error";
            if (exception == AccountNotFoundException.class) {
                message = "Cannot find account";
            }

            return CommonResult.failed(message, null);
        }

        User user = (User) request.getAttribute(AccountRealm.LOGIN_USER_ATTR);
        if (user == null) {
            Integer userId = subject.getPrincipals().oneByType(Integer.class);
            user = userService.findUser(userId);
        }

        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setUser(user);
        accountInfo.setAuthorizationInfo(accountService.getUserAuthorizationInfo(user.getUsername(), user.getId()));

        LoginResult result = new LoginResult();
        result.setToken(JWTUtils.createToken(user, 1, algorithm));
        result.setAccountInfo(accountInfo);

        return CommonResult.success(result);
    }
}
